~ chicken-core (chicken-5) /manual/Module (chicken foreign)


  1[[tags: manual]]
  2[[toc:]]
  3
  4== Module (chicken foreign)
  5
  6This module provides a ''foreign function interface'' to access externally
  7defined functions and variables in C-compatible languages, as well as
  8operating-system specific functionality.
  9
 10Note that this interface is source-based, since CHICKEN translates
 11Scheme code to C. It is not binary, as in many other Scheme implementations.
 12
 13Several special forms of this interface refer to ''foreign type specifiers'',
 14consult the [[/manual/Foreign type specifiers|relevant chapter]] of this manual for
 15more information.
 16
 17
 18== Accessing external objects
 19
 20=== foreign-code
 21
 22<macro>(foreign-code STRING ...)</macro>
 23
 24Executes the embedded C/C++ code {{STRING ...}}, which should
 25be a sequence of C statements, which are executed and return an unspecified result.
 26
 27<enscript highlight=scheme>
 28(foreign-code "doSomeInitStuff();")     =>  #<unspecified>
 29</enscript>
 30
 31Code wrapped inside {{foreign-code}} may not invoke callbacks into Scheme.
 32
 33
 34=== foreign-value
 35
 36<macro>(foreign-value CODE TYPE)</macro>
 37
 38Evaluates the embedded C/C++ expression {{CODE}} (which may be a string or symbol), returning a value of type given
 39in the foreign-type specifier {{TYPE}}.
 40
 41<enscript highlight=scheme>
 42(print (foreign-value "my_version_string" c-string))
 43</enscript>
 44
 45
 46=== foreign-declare
 47
 48<macro>(foreign-declare STRING ...)</macro>
 49
 50Include given strings verbatim into header of generated file.
 51
 52
 53=== define-foreign-type
 54
 55<macro>(define-foreign-type NAME TYPE [ARGCONVERT [RETCONVERT]])</macro>
 56
 57Defines an alias for {{TYPE}} with the name {{NAME}} (a symbol).
 58{{TYPE}} may be a type-specifier or a string naming a C type. The
 59namespace of foreign type specifiers is separate from the normal
 60Scheme namespace.  The optional arguments {{ARGCONVERT}} and
 61{{RETCONVERT}} should evaluate to procedures that map argument- and
 62result-values to a value that can be transformed to {{TYPE}}:
 63
 64<enscript highlight=scheme>
 65(define-foreign-type char-vector 
 66  nonnull-c-string
 67  (compose list->string vector->list)
 68  (compose list->vector string->list) )
 69
 70(define strlen
 71  (foreign-lambda int "strlen" char-vector) )
 72
 73(strlen '#(#\a #\b #\c))                      ==> 3
 74
 75(define memset
 76  (foreign-lambda char-vector "memset" char-vector char int) )
 77
 78(memset '#(#_ #_ #_) #\X 3)                ==> #(#\X #\X #\X)
 79</enscript>
 80
 81Foreign type-definitions are only visible in the compilation-unit in which
 82they are defined, so use {{include}} to use the same definitions
 83in multiple files.
 84
 85
 86=== foreign-type-size
 87
 88<macro>(foreign-type-size TYPE)</macro>
 89
 90Returns the size of the storage required to hold values of the
 91given foreign type {{TYPE}}. This is basically equivalent to
 92
 93<enscript highlight=scheme>
 94(foreign-value "sizeof(TYPE)" size_t)
 95</enscript>
 96
 97but also handles user-defined types and allows "TYPE" to be a string,
 98which will be given literally to the {{sizeof}} operator.
 99
100
101=== define-foreign-variable
102
103<macro>(define-foreign-variable NAME TYPE [STRING])</macro>
104
105Defines a foreign variable of name {{NAME}} (a symbol). {{STRING}}
106should be the real name of a foreign variable or parameterless
107macro. If {{STRING}} is not given, then the variable name {{NAME}}
108will be converted to a string and used instead. All references and
109assignments (via {{set!}}) are modified to correctly convert values
110between Scheme and C representation. This foreign variable can only be
111accessed in the current compilation unit, but the name can be
112lexically shadowed.  Note that {{STRING}} can name an arbitrary C
113expression. If no assignments are performed, then {{STRING}} doesn't
114even have to specify an lvalue.
115See that {{define-foreign-variable}} will not generate C declarations
116or memory allocation code; use it to include references to variables
117in external C code. To actually create Scheme variables visible from C,
118use {{define-external}} (see the Manual section on
119[[/manual/Module (chicken foreign)#Callbacks|Callbacks]]).
120For example, the following code:
121<enscript lang="scheme">
122(import (chicken foreign))
123(define-foreign-variable x double "var_x")
124(print x)
125</enscript>
126will not work, because a reference to {{var_x}} will be inserted in the C code,
127but no declaration will be included (this can be easily verified by translating
128the program into C with {{csc -t program.scm}}). Changing the second line to
129{{(define-external x double 0.5)}} will work (and the value 0.5 will be printed).
130
131=== foreign-lambda
132
133<macro>(foreign-lambda RETURNTYPE NAME ARGTYPE ...)</macro>
134
135Represents a
136binding to an external routine. This form can be used in the position
137of an ordinary {{lambda}} expression. {{NAME}} specifies the
138name of the external procedure and should be a string or a symbol.
139
140
141=== foreign-lambda*
142
143<macro>(foreign-lambda* RETURNTYPE ((ARGTYPE VARIABLE) ...) STRING ...)</macro>
144
145Similar to {{foreign-lambda}}, but instead of generating code to
146call an external function, the body of the C procedure is directly given
147in {{STRING ...}}:
148
149<enscript highlight=scheme>
150(define my-strlen
151  (foreign-lambda* int ((c-string str))
152    "int n = 0;
153     while(*(str++)) ++n;
154     C_return(n);") )
155
156(my-strlen "one two three")             ==> 13
157</enscript>
158
159For obscure technical reasons you should use the {{C_return}} macro instead of the normal {{return}} statement
160to return a result from the foreign lambda body as some cleanup code has to be run before execution
161commences in the calling code.
162
163=== foreign-safe-lambda
164
165<macro>(foreign-safe-lambda RETURNTYPE NAME ARGTYPE ...)</macro>
166
167This is similar to {{foreign-lambda}}, but also allows the called
168function to call Scheme functions. See [[/manual/Module (chicken foreign)#Callbacks|Callbacks]].
169
170
171=== foreign-safe-lambda*
172
173<macro>(foreign-safe-lambda* RETURNTYPE ((ARGTYPE VARIABLE)...) STRING ...)</macro>
174
175This is similar to {{foreign-lambda*}}, but also allows the called
176function to call Scheme functions and allocate Scheme data-objects.
177See [[/manual/Module (chicken foreign)#Callbacks|Callbacks]].
178
179
180
181=== foreign-primitive
182
183<macro>(foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING ...)</macro>
184
185This is also similar to {{foreign-lambda*}} but the code will be
186executed in a ''primitive'' CPS context, which means it will not
187actually return, but call its continuation on exit. This means that code
188inside this form may allocate Scheme data on the C stack (the
189''nursery'') with {{C_alloc}} (see below). You can return multiple
190values inside the body of the {{foreign-primitive}} form by using
191the following C code:
192
193<enscript highlight=scheme>
194C_word av[N + 2] = { C_SCHEME_UNDEFINED, C_k, X1, ... };
195C_values(N + 2, av);
196</enscript>
197
198where {{N}} is the number of values to be returned, and {{X1, ...}}
199are the results, which should be Scheme data objects.
200See [[/manual/C interface#constructors|Constructors]] for the APIs to construct Scheme data objects from C primitives.
201When returning multiple values, the return-type should be omitted.
202Of course, if you have to dynamically compute the values, you do not have to use C's 
203array initialization syntax, but you can just assign them one by one.
204
205Returning just a single value can still be done via the {{C_return(...)}} macro.
206
207
208== Callbacks
209
210
211To enable an external C function to call back to Scheme, the form
212{{foreign-safe-lambda}} (or {{foreign-safe-lambda*}})
213has to be used. This generates special code to save and restore important
214state information during execution of C code. There are two ways of
215calling Scheme procedures from C: the first is to invoke the runtime
216function {{C_callback}} with the closure to be called and the number
217of arguments.  The second is to define an externally visible wrapper
218function around a Scheme procedure with the {{define-external}}
219form.
220
221Note: the names of all functions, variables and macros exported by the
222CHICKEN runtime system start with {{C_}}. It is advisable to
223use a different naming scheme for your own code to avoid name clashes.
224Callbacks (defined by {{define-external}})
225do not capture the lexical environment.
226
227Non-local exits leaving the scope of the invocation of a callback from Scheme into C
228will not remove the C call-frame from the stack (and will result in a memory
229leak).  '''Note:''' The same applies to
230SRFI-18 threading, which is implemented with {{call/cc}};
231additionally, if you enter one callback, switch threads and then exit
232a different callback, your program is likely to crash.
233
234
235=== define-external
236
237<macro>(define-external [QUALIFIERS] (NAME (ARGUMENTTYPE1 VARIABLE1) ...) RETURNTYPE BODY ...)</macro><br>
238<macro>(define-external NAME TYPE [INIT])</macro>
239
240The first form defines an externally callable Scheme
241procedure. {{NAME}} should be a symbol, which, when converted to a
242string, represents a legal C identifier. {{ARGUMENTTYPE1 ...}} and
243{{RETURNTYPE}} are foreign type specifiers for the argument variables
244{{VAR1 ...}} and the result, respectively.  {{QUALIFIERS}}
245is an optional qualifier for the foreign procedure definition, like
246{{__stdcall}}.
247
248<enscript highlight=scheme>
249(define-external (foo (c-string x)) int (string-length x))
250</enscript>
251
252You can use [[/manual/Module (chicken foreign)#location|{{location}}]]
253to get a pointer to the defined C function, which can be passed to a
254C function that takes a callback function pointer argument, for example.
255
256The second form of {{define-external}} can be used to define
257variables that are accessible from foreign code. It declares
258a global variable named by the symbol {{NAME}} that
259has the type {{TYPE}}. {{INIT}} can be an arbitrary
260expression that is used to initialize the variable. {{NAME}} is
261accessible from Scheme just like any other foreign variable defined by
262{{define-foreign-variable}}.
263
264<enscript highlight=scheme>
265(define-external foo int 42)
266((foreign-lambda* int ()
267  "C_return(foo);"))           ==> 42
268</enscript>
269
270'''Note:''' don't be tempted to
271assign strings or bytevectors to external variables. Garbage collection
272moves those objects around, so it is a very bad idea to assign pointers
273to heap-data. If you have to do so, then copy the data object into
274statically allocated memory (for example by using {{object-evict}}).
275
276Results of type {{scheme-object}} returned by {{define-external}}
277are always allocated in the secondary heap, that is, not in the stack.
278
279=== C_callback
280
281 [C function] C_word C_callback (C_word closure, int argc)
282
283This function can be used to invoke the Scheme procedure {{closure}}.
284{{argc}} should contain the number of arguments that are passed to
285the procedure on the temporary stack. Values are put onto the temporary
286stack with the {{C_save}} macro.
287
288=== C_callback_adjust_stack
289
290 [C function] void C_callback_adjust_stack (C_word *ptr, int size)
291
292The runtime-system uses the stack as a special allocation area and
293internally holds pointers to estimated limits to distinguish between
294Scheme data objects inside the stack from objects outside of it.  If
295you invoke callbacks at wildly differing stack-levels, these limits
296may shift from invocation to invocation. Callbacks defined with
297{{define-external}} will perform appropriate adjustments
298automatically, but if you invoke {{C_callback}} manually, you should
299perform a {{C_callback_adjust_stack}} to make sure the internal limits
300are set properly. {{ptr}} should point to some data object on the
301stack and {{size}} is the number of words contained in the data object
302(or some estimate). The call will make sure the limits are adjusted so
303that the value pointed to by {{ptr}} is located in the stack.
304
305== Locations
306
307It is also possible to define variables containing unboxed C data,
308so called ''locations''. It should be noted that locations may
309only contain simple data, that is: everything that fits into a
310machine word, and double-precision floating point values. 
311
312
313
314=== define-location
315
316<macro>(define-location NAME TYPE [INIT])</macro>
317
318Identical to {{(define-external NAME TYPE [INIT])}}, but the variable
319is not accessible from outside of the current compilation unit (it is 
320declared {{static}}).
321
322=== let-location
323
324<macro>(let-location ((NAME TYPE [INIT]) ...) BODY ...)</macro>
325
326Defines a lexically bound location.
327
328=== location
329
330<macro>(location NAME)</macro><br>
331<macro>(location X)</macro>
332<read>#$</read>
333
334This form returns a pointer object
335that contains the address of the variable {{NAME}}.
336If the argument to {{location}} is not a location defined by {{define-location}},
337{{define-external}} or {{let-location}}, then
338
339 (location X)
340
341is essentially equivalent to
342
343 (make-locative X)
344
345(See the [[/manual/Module (chicken locative)|manual section on locatives]] for more
346information about locatives)
347
348Note that {{(location X)}} may be abbreviated as {{#$X}}.
349
350<enscript highlight=scheme>
351(define-external foo int)
352((foreign-lambda* void (((c-pointer int) ip)) "*ip = 123;")
353  (location foo))
354foo                                                                    ==> 123
355</enscript>
356
357This facility is especially useful in situations, where a C function
358returns more than one result value:
359
360<enscript highlight=scheme>
361#>
362#include <math.h>
363<#
364
365(define modf
366  (foreign-lambda double "modf" double (c-pointer double)) )
367
368(let-location ([i double])
369  (let ([f (modf 1.99 (location i))])
370    (print "i=" i ", f=" f) ) )
371</enscript>
372
373See [[/location-and-c-string-star|location and c-string*]]
374for a tip on returning a {{c-string*}} type.
375
376{{location}} returns a value of type {{c-pointer}}, when given
377the name of a callback-procedure defined with {{define-external}}.
378
379---
380Previous: [[Module (chicken flonum)]]
381
382Next: [[Module (chicken format)]]
Trap